{
    This file is part of the Free Component Library (FCL)
    Copyright (c) 1999-2002 by the Free Pascal development team

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}

{****************************************************************************}
{*                             TThread                                      *}
{****************************************************************************}

const
 ThreadCount: longint = 0;

 ThreadPriorities: array[TThreadPriority] of system.TThreadPriority = (tpPaused, tpLow, tpLow, system.tpNormal, system.tpNormal, tpHigh, tpRealtime);

(* Implementation of exported functions *)

procedure AddThread (T: TThread);
begin
	Inc(ThreadCount);
end;


procedure RemoveThread (T: TThread);
begin
	Dec(ThreadCount);
end;


procedure TThread.CallOnTerminate;
begin
	FOnTerminate(Self);
end;


function TThread.GetPriority: TThreadPriority;
var tp: system.TThreadPriority;
begin
	if GetThreadPriority(handle, @tp) = R_OK then
		result := tpNormal
	else
		result := tpNormal;
end;


procedure TThread.SetPriority(Value: TThreadPriority);
begin
	SetThreadPriority(FHandle, ThreadPriorities[value]);
end;


procedure TThread.SetSuspended(Value: Boolean);
begin
	if Value <> FSuspended then
	begin
		if Value then
			Suspend
		else
			Resume;
	end;
end;


procedure TThread.DoTerminate;
begin
	if Assigned (FOnTerminate) then
		Synchronize(@CallOnTerminate);
end;


constructor TThread.Create(CreateSuspended: Boolean; const StackSize: SizeUInt = DefaultStackSize);
begin
	inherited Create;
	AddThread (Self);
	
	FHandle := CreateThread(-1, @ThreadProc, pointer(self), StackSize, system.tpNormal);
	FThreadID := FHandle;
	
	if FHandle = InvalidHandle then
		raise EThread.create('Failed to create new thread');
	
	if not CreateSuspended then
		WakeupThread(FHandle);
end;


destructor TThread.Destroy;
begin
	if not FFinished and not Suspended then
	begin
		Terminate;
		WaitFor;
	end;
	
	inherited Destroy;
end;

procedure TThread.Resume;
begin
	WakeupThread(FHandle);
end;


procedure TThread.Suspend;
begin
	SleepThread(FHandle);
end;


procedure TThread.Terminate;
begin
	FTerminated := true;
end;


function TThread.WaitFor: Integer;
begin
	result := -1;
end;


